/*
 * @Author Esteban
 */
public class Cache {
	//atributos de clase
	private ConjuntoCache[] cache;
	/**
	 * inicializa la memoria cache con una memoria ram
	 * @param memoria, referencia tipo RAM de la memoria principal
	 */
	public Cache(RAM memoria) {
		ConjuntoCache.setMemoria(memoria);
		cache = new ConjuntoCache[Utilidades.NUMEROCONJUNTOS];
		for (int i = 0; i < Utilidades.NUMEROCONJUNTOS; i++) {
			cache[i] = new ConjuntoCache();
		}
	}
	/**
	 * Metodo para comprobar si una direccion se encuentra en la cache
	 * @param linea, direccion del dato en Ram
	 * @return, booleano true para aceirto false de lo contrario
	 */
	public boolean comprobar(int linea) {
		int grupo = Utilidades.calcularGrupo(linea);
		int tag = Utilidades.calcularTag(linea);
		return cache[grupo].buscarTag(tag);
	}
	/**
	 * metodo que guarda un bloque de datos a una linea de cache
	 * @param bloque, bloque de datos tipo int[]
	 * @param linea, direccion en la ram
	 */
	public void guardarBloque(int[] bloque, int linea) {
		int grupo = Utilidades.calcularGrupo(linea);
		LineaCache lc = new LineaCache(bloque, linea);
		cache[grupo].insertar(lc);
	}
	/**
	 * metodo que actualiza cada uno de los grupos de la cache
	 */
	public void actualizar() {
		for (int i = 0; i < cache.length; i++) {
			cache[i].actualizarConjunto();
		}
	}
	/**
	 * metodo para reemplzar una linea que contiene un dato nuevo
	 * @param nuevaLinea, linea de cache modificada
	 */
	public void reemplazarLinea(LineaCache nuevaLinea) {
		cache[nuevaLinea.getGrupo()].reemplazar(nuevaLinea);
	}
	/**
	 * retornar un conjunto de cache
	 * @param conjunto, el indice del conjunto
	 * @return, objeto tipo ConjuntoCache
	 */
	public ConjuntoCache getConjunto(int conjunto) {
		return cache[conjunto];
	}
	/**
	 * metodo para obtener las lineas actualizadas de la cache
	 * @param conjunto, indice del conjunto al cual obtener las lineas actualizadas
	 * @return, arreglo de booleanos con true para actualizado y false de lo contrario
	 */
	public boolean[] getActualizados(int conjunto) {
		return cache[conjunto].getActualizados();
	}
	/**
	 * obtener una linea segun el tag y el conjunto
	 * @param tag, tag de la linea a obtener
	 * @param conjunto, conjunto del cual quiero  obtener
	 * @return, objeto tipo LineaCache
	 */
	public LineaCache getLinea(int tag, int conjunto) {
		return cache[conjunto].getLinea(tag);
	}
	/**
	 * metodo para obtener un indice de un grupo, este indice indica en que posicion va el FIFO
	 * @param conjunto, indice del conjunto
	 * @return, int indice
	 */
	public int getIndice(int conjunto) {
		return cache[conjunto].getIndice();
	}
}
